import random
import json
from config import Config

class Cell:
    """表示单个细胞"""
    def __init__(self, x: int, y: int, alive: bool = False):
        self.x = x
        self.y = y
        self.alive = alive
        self.next_state = alive

    def update(self):
        """更新细胞状态"""
        self.alive = self.next_state

class GameLogic:
    """游戏核心逻辑"""
    def __init__(self, width: int, height: int):
        self.width = width
        self.height = height
        self.grid = [[Cell(x, y) for x in range(width)] for y in range(height)]
        self.generation = 0
        self.running = False
        self.paused = False
        self.active_cells = set()  # 用于优化的活细胞集合

    def resize_grid(self, new_width: int, new_height: int):
        """调整网格大小"""
        # 停止游戏
        self.running = False
        self.paused = False
        
        # 创建新的网格
        new_grid = [[Cell(x, y) for x in range(new_width)] for y in range(new_height)]
        
        # 复制现有细胞状态
        for y in range(min(self.height, new_height)):
            for x in range(min(self.width, new_width)):
                if self.grid[y][x].alive:
                    new_grid[y][x].alive = True
                    new_grid[y][x].next_state = True
        
        # 更新网格
        self.width = new_width
        self.height = new_height
        self.grid = new_grid
        
        # 更新活动细胞集合
        self.active_cells = set()
        for y in range(self.height):
            for x in range(self.width):
                if self.grid[y][x].alive:
                    self.active_cells.add((x, y))
        
        # 重置代数
        self.generation = 0

    def load_pattern(self, pattern: list):
        """加载预设图案"""
        # 停止游戏
        self.running = False
        self.paused = False
        
        # 清空当前网格
        self.clear()
        
        # 计算图案放置的位置（居中）
        pattern_width = len(pattern[0])
        pattern_height = len(pattern)
        start_x = (self.width - pattern_width) // 2
        start_y = (self.height - pattern_height) // 2
        
        # 放置图案
        for y, row in enumerate(pattern):
            for x, cell in enumerate(row):
                if cell and 0 <= start_x + x < self.width and 0 <= start_y + y < self.height:
                    self.grid[start_y + y][start_x + x].alive = True
                    self.grid[start_y + y][start_x + x].next_state = True
                    self.active_cells.add((start_x + x, start_y + y))
        
        # 重置代数
        self.generation = 0

    def toggle_cell(self, x: int, y: int):
        """切换指定位置细胞的状态"""
        if 0 <= x < self.width and 0 <= y < self.height:
            cell = self.grid[y][x]
            cell.alive = not cell.alive
            cell.next_state = cell.alive
            if cell.alive:
                self.active_cells.add((x, y))
            else:
                self.active_cells.discard((x, y))

    def get_neighbors(self, x: int, y: int) -> int:
        """获取指定位置周围的活细胞数量"""
        count = 0
        for dy in [-1, 0, 1]:
            for dx in [-1, 0, 1]:
                if dx == 0 and dy == 0:
                    continue
                nx, ny = x + dx, y + dy
                if 0 <= nx < self.width and 0 <= ny < self.height:
                    if self.grid[ny][nx].alive:
                        count += 1
        return count

    def update(self):
        """更新一代"""
        if not self.running or self.paused:
            return

        # 获取需要检查的细胞集合
        cells_to_check = set()
        for x, y in self.active_cells:
            cells_to_check.add((x, y))
            # 添加周围的细胞
            for dy in [-1, 0, 1]:
                for dx in [-1, 0, 1]:
                    nx, ny = x + dx, y + dy
                    if 0 <= nx < self.width and 0 <= ny < self.height:
                        cells_to_check.add((nx, ny))

        # 计算下一代状态
        new_active_cells = set()
        for x, y in cells_to_check:
            cell = self.grid[y][x]
            neighbors = self.get_neighbors(x, y)
            
            if cell.alive:
                # 活细胞的规则
                cell.next_state = neighbors in [2, 3]
            else:
                # 死细胞的规则
                cell.next_state = neighbors == 3

            if cell.next_state:
                new_active_cells.add((x, y))

        # 更新所有细胞状态
        for x, y in cells_to_check:
            self.grid[y][x].update()

        self.active_cells = new_active_cells
        self.generation += 1

    def clear(self):
        """清空网格"""
        for row in self.grid:
            for cell in row:
                cell.alive = False
                cell.next_state = False
        self.active_cells.clear()
        self.generation = 0

    def randomize(self, probability: float = 0.3):
        """随机填充网格"""
        self.clear()
        for y in range(self.height):
            for x in range(self.width):
                if random.random() < probability:
                    self.toggle_cell(x, y)

    def get_alive_count(self) -> int:
        """获取当前活细胞数量"""
        return len(self.active_cells)

    def save_state(self, filename: str):
        """保存当前状态到文件"""
        state = {
            "generation": self.generation,
            "width": self.width,
            "height": self.height,
            "cells": [[int(cell.alive) for cell in row] for row in self.grid]
        }
        with open(filename, 'w') as f:
            json.dump(state, f)

    def load_state(self, filename: str):
        """从文件加载状态"""
        with open(filename, 'r') as f:
            state = json.load(f)
            
        if (state["width"] != self.width or 
            state["height"] != self.height):
            raise ValueError("Grid dimensions do not match")

        self.clear()
        self.generation = state["generation"]
        
        for y in range(self.height):
            for x in range(self.width):
                if state["cells"][y][x]:
                    self.toggle_cell(x, y)

    def start(self):
        """开始游戏"""
        self.running = True
        self.paused = False

    def stop(self):
        """停止游戏"""
        self.running = False
        self.paused = False

    def pause(self):
        """暂停游戏"""
        if self.running:
            self.paused = not self.paused

    def step(self):
        """单步执行"""
        was_running = self.running
        was_paused = self.paused
        self.running = True
        self.paused = False
        self.update()
        self.running = was_running
        self.paused = was_paused